package net.maku.events.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import net.maku.events.dao.ActivityBriskWalkFeatureDao;
import net.maku.events.dao.UserPointsRecordsDao;
import net.maku.events.entity.ActivityBriskWalkFeatureEntity;
import net.maku.events.entity.ActivitySnapshotEntity;
import net.maku.events.entity.UserPointsRecordsEntity;
import net.maku.events.enums.ActivityTypeEnum;
import net.maku.events.enums.WhetherAddEnum;
import net.maku.events.enums.WhetherPointsEnum;
import net.maku.events.service.ActivitySnapshotService;
import net.maku.events.service.UserPointsRecordsService;
import net.maku.events.vo.UserSnapshotAuditVO;
import net.maku.framework.common.constant.Constant;
import net.maku.framework.common.utils.DateUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.events.convert.UserSnapshotConvert;
import net.maku.events.entity.UserSnapshotEntity;
import net.maku.events.query.UserSnapshotQuery;
import net.maku.events.vo.UserSnapshotVO;
import net.maku.events.dao.UserSnapshotDao;
import net.maku.events.service.UserSnapshotService;
import net.maku.framework.security.user.SecurityUser;
import net.maku.member.dao.MemberUserDao;
import net.maku.member.entity.MemberUserEntity;
import net.maku.member.service.MemberUserService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户随手拍作品
 *
 * @author 阿沐 babamu@126.com
 * @since 1.0.0 2025-03-22
 */
@Service
@AllArgsConstructor
public class UserSnapshotServiceImpl extends BaseServiceImpl<UserSnapshotDao, UserSnapshotEntity> implements UserSnapshotService {

    private final MemberUserService memberUserService;

    private final ActivitySnapshotService activitySnapshotService;

    private final UserPointsRecordsService userPointsRecordsService;

    private final ActivityBriskWalkFeatureDao activityBriskWalkFeatureDao;

    @Override
    public PageResult<UserSnapshotVO> page(UserSnapshotQuery query) {
        IPage<UserSnapshotEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        return new PageResult<>(BeanUtil.copyToList(page.getRecords(), UserSnapshotVO.class), page.getTotal());
    }

    private LambdaQueryWrapper<UserSnapshotEntity> getWrapper(UserSnapshotQuery query) {
        LambdaQueryWrapper<UserSnapshotEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(query.getDescription()), UserSnapshotEntity::getDescription, query.getDescription())
                .eq(ObjectUtils.isNotEmpty(query.getAuditStatus()), UserSnapshotEntity::getAuditStatus, query.getAuditStatus())
                .eq(ObjectUtils.isNotEmpty(query.getWhetherChoiceness()), UserSnapshotEntity::getWhetherChoiceness, query.getWhetherChoiceness())
                .orderByDesc(UserSnapshotEntity::getCreateTime);
        if (StringUtils.isNotEmpty(query.getUserName())) {
            List<MemberUserEntity> entityList = memberUserService.list(new LambdaQueryWrapper<MemberUserEntity>().like(MemberUserEntity::getRealName, query.getUserName()));
            if (CollectionUtils.isNotEmpty(entityList)) {
                wrapper.in(UserSnapshotEntity::getUserId, entityList.stream().map(MemberUserEntity::getId).toList());
            } else {
                wrapper.eq(UserSnapshotEntity::getId, 0);
            }
        }
        return wrapper.orderByDesc(UserSnapshotEntity::getWhetherChoiceness).orderByDesc(UserSnapshotEntity::getCreateTime);
    }

    @Override
    public void save(UserSnapshotVO vo) {
        UserSnapshotEntity entity = UserSnapshotConvert.INSTANCE.convert(vo);

        baseMapper.insert(entity);
    }

    @Override
    public void update(UserSnapshotVO vo) {
        UserSnapshotEntity entity = UserSnapshotConvert.INSTANCE.convert(vo);

        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void audit(UserSnapshotAuditVO auditVO) {
        if (auditVO.getAuditStatus().equals(2)) {
            LambdaUpdateWrapper<UserSnapshotEntity> updateWrapper = new LambdaUpdateWrapper<UserSnapshotEntity>()
                    .set(UserSnapshotEntity::getAuditStatus, auditVO.getAuditStatus())
                    .in(UserSnapshotEntity::getId, auditVO.getIdList());
            this.update(updateWrapper);
        } else if (auditVO.getAuditStatus().equals(1)) {
            List<UserSnapshotEntity> userSnapshotEntityList = this.listByIds(auditVO.getIdList());
            List<MemberUserEntity> memberUserEntityList = memberUserService.listByIds(userSnapshotEntityList.stream().map(UserSnapshotEntity::getUserId).toList());
            Map<Long, MemberUserEntity> memberUserEntityMap = memberUserEntityList.stream().collect(Collectors.toMap(MemberUserEntity::getId, Function.identity()));
            List<ActivitySnapshotEntity> activitySnapshotEntityList = activitySnapshotService.listByIds(userSnapshotEntityList.stream().map(UserSnapshotEntity::getSnapshotId).toList());
            Map<Long, ActivitySnapshotEntity> snapshotEntityMap = activitySnapshotEntityList.stream().collect(Collectors.toMap(ActivitySnapshotEntity::getId, Function.identity()));
            List<Long> walkFeatureIdList = userSnapshotEntityList.stream().map(UserSnapshotEntity::getWalkFeatureId).filter(Objects::nonNull).toList();
            Map<Long, ActivityBriskWalkFeatureEntity> walkFeatureEntityMap = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(walkFeatureIdList)) {
                List<ActivityBriskWalkFeatureEntity> walkFeatureEntityList = activityBriskWalkFeatureDao.selectBatchIds(walkFeatureIdList);
                walkFeatureEntityMap = walkFeatureEntityList.stream().collect(Collectors.toMap(ActivityBriskWalkFeatureEntity::getId, Function.identity()));
            }
            Map<Long, ActivityBriskWalkFeatureEntity> finalWalkFeatureEntityMap = walkFeatureEntityMap;
            List<UserPointsRecordsEntity> pointsRecordsEntityList = new ArrayList<>();
            userSnapshotEntityList.forEach(entity -> {
                if (entity.getAuditStatus().equals(Constant.FAIL)) {
                    ActivitySnapshotEntity activitySnapshotEntity = snapshotEntityMap.get(entity.getSnapshotId());
                    MemberUserEntity memberUserEntity = memberUserEntityMap.get(entity.getUserId());
                    if (ObjectUtils.isNotEmpty(entity.getWalkFeatureId())) {
                        ActivityBriskWalkFeatureEntity featureEntity = finalWalkFeatureEntityMap.get(entity.getWalkFeatureId());
                        if (featureEntity.getWhetherPoints().equals(WhetherPointsEnum.YES.getType())) {
                            //是否增加积分
                            insertUserPointsRecords(featureEntity.getBriskWalkId(), ActivityTypeEnum.WALK_ACTIVITY.getBusinessType(), activitySnapshotEntity.getEarningsPoints(), entity.getCreateTime(), memberUserEntity, pointsRecordsEntityList);
                        }
                    } else {
                        insertUserPointsRecords(activitySnapshotEntity.getId(), ActivityTypeEnum.SNAPSHOT.getBusinessType(), activitySnapshotEntity.getEarningsPoints(), entity.getCreateTime(), memberUserEntity, pointsRecordsEntityList);
                    }
                    entity.setAuditStatus(auditVO.getAuditStatus());
                }
            });
            userPointsRecordsService.saveBatch(pointsRecordsEntityList);
            memberUserService.saveOrUpdateBatch(memberUserEntityList);
            this.saveOrUpdateBatch(userSnapshotEntityList);
        }
    }

    /**
     * 添加积分
     *
     * @param businessId   业务id
     * @param businessType 业务类型
     * @param points       积分
     */
    private void insertUserPointsRecords(Long businessId, Integer businessType, Double points, LocalDateTime createTime, MemberUserEntity memberUserEntity, List<UserPointsRecordsEntity> pointsRecordsEntityList) {
        UserPointsRecordsEntity entity = new UserPointsRecordsEntity();
        entity.setBusinessId(businessId);
        entity.setBusinessType(businessType);
        entity.setPoints(points);
        entity.setWhetherAdd(WhetherAddEnum.ADD.getType());
        entity.setUserId(memberUserEntity.getId());
        pointsRecordsEntityList.add(entity);
        entity.setCreateTime(createTime);
        memberUserEntity.setPoints(memberUserEntity.getPoints() + points);
    }


    @Override
    public void whetherChoiceness(Long id, Integer status) {
        LambdaUpdateWrapper<UserSnapshotEntity> updateWrapper = new LambdaUpdateWrapper<UserSnapshotEntity>()
                .set(UserSnapshotEntity::getWhetherChoiceness, status)
                .eq(UserSnapshotEntity::getId, id);
        this.update(updateWrapper);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

}